package cn.zz.camerasdk.views;

/**
 * author: zhu on 2017/7/7 16:54
 * email: mackkill@gmail.com
 */


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

import cn.zz.camerasdk.utils.MResource;

public class HSuperImageView extends View {
    private Context mContext;
    static final float MAX_SCALE = 2.0F;
    float imageW;
    float imageH;
    int rotatedImageW;
    int rotatedImageH;
    int viewW;
    int viewH;
    int viewL;
    int viewT;
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    static final int ROTATE = 3;
    static final int ZOOM_OR_ROTATE = 4;
    int mode = 0;
    PointF pA = new PointF();
    PointF pB = new PointF();
    PointF mid = new PointF();
    PointF lastClickPos = new PointF();
    long lastClickTime = 0L;
    double rotation = 0.0D;
    float dist = 1.0F;
    private Bitmap mBitmap;
    private Bitmap delmB;
    private Bitmap ctrlmB;
    private final Paint paint;
    public Point cpoint;
    public float jd;
    public float sfxs;
    public int wW = 0;
    public int wH = 0;
    Point iconP1;
    Point iconP2;
    Point np1;
    Point np2;
    Point np3;
    Point np4;
    int dx;
    int dy;
    int sticknum;
    private boolean stickEditMode = true;
    int resId_edit_ic_launcher;
    int resId_edit_del;
    int resId_edit_control;
    private HSuperImageView.OnStickerListener stickerListener;

    public HSuperImageView(Context context) {
        super(context);
        this.mContext = context;
        this.paint = new Paint();
        this.paint.setAntiAlias(true);
        this.paint.setStyle(Style.STROKE);
        this.init();
    }

    public HSuperImageView(Context context, int sticknum) {
        super(context);
        this.mContext = context;
        this.sticknum = sticknum;
        this.resId_edit_ic_launcher = MResource.getIdByName(this.mContext, "drawable", "ic_launcher");
        this.resId_edit_del = MResource.getIdByName(this.mContext, "drawable", "camerasdk_edit_del");
        this.resId_edit_control = MResource.getIdByName(this.mContext, "drawable", "camerasdk_edit_control");
        this.paint = new Paint();
        this.paint.setAntiAlias(true);
        this.paint.setStyle(Style.STROKE);
        this.init();
    }

    public HSuperImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.paint = new Paint();
        this.paint.setAntiAlias(true);
        this.paint.setStyle(Style.STROKE);
        this.init();
    }

    public HSuperImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.paint = new Paint();
        this.paint.setAntiAlias(true);
        this.paint.setStyle(Style.STROKE);
        this.init();
    }

    public void init() {
        this.mBitmap = BitmapFactory.decodeResource(this.getResources(), this.resId_edit_ic_launcher);
        this.delmB = BitmapFactory.decodeResource(this.getResources(), this.resId_edit_del);
        this.ctrlmB = BitmapFactory.decodeResource(this.getResources(), this.resId_edit_control);
        this.wW = this.delmB.getWidth() / 2;
        this.wH = this.delmB.getHeight() / 2;
        this.setImageBitmap(this.mBitmap, new Point(200, 200), 30.0F, 0.5F);
    }

    public void init(Bitmap bitmap) {
        this.mBitmap = bitmap;
        this.delmB = BitmapFactory.decodeResource(this.getResources(), this.resId_edit_del);
        this.ctrlmB = BitmapFactory.decodeResource(this.getResources(), this.resId_edit_control);
        this.wW = this.delmB.getWidth() / 2;
        this.wH = this.delmB.getHeight() / 2;
        DisplayMetrics dm = this.getResources().getDisplayMetrics();
        int displayWidth = dm.widthPixels;
        int displayHeight = dm.heightPixels;
        int x = displayWidth / 2;
        int y = displayHeight * 1 / 3;
        this.setImageBitmap(this.mBitmap, new Point(x, y), 0.0F, 1.0F);
    }

    public void setViewWH(int w, int h, int l, int t) {
        int nviewW = w + this.wW * 2;
        int nviewH = h + this.wH * 2;
        int nviewL = l - this.wW;
        int nviewT = t - this.wH;
        this.viewW = nviewW;
        this.viewH = nviewH;
        this.viewL = nviewL;
        this.viewT = nviewT;
        this.layout(this.viewL, this.viewT, this.viewL + this.viewW, this.viewT + this.viewH);
    }

    public void setCPoint(Point c) {
        this.cpoint = c;
        this.setViewWH(this.rotatedImageW, this.rotatedImageH, this.cpoint.x - this.rotatedImageW / 2, this.cpoint.y - this.rotatedImageH / 2);
    }

    public void setImageBitmap(Bitmap bm, Point c, float jd, float sf) {
        this.mBitmap = bm;
        this.cpoint = c;
        this.jd = jd;
        this.sfxs = sf;
        this.drawRectR(0, 0, (int)((float)this.mBitmap.getWidth() * this.sfxs), (int)((float)this.mBitmap.getHeight() * this.sfxs), jd);
        this.matrix = new Matrix();
        this.matrix.setScale(sf, sf);
        this.matrix.postRotate(jd % 360.0F, (float)this.mBitmap.getWidth() * sf / 2.0F, (float)this.mBitmap.getHeight() * sf / 2.0F);
        this.matrix.postTranslate((float)(this.dx + this.wW), (float)(this.dy + this.wH));
        this.setViewWH(this.rotatedImageW, this.rotatedImageH, this.cpoint.x - this.rotatedImageW / 2, this.cpoint.y - this.rotatedImageH / 2);
    }

    public static Point roationPoint(Point target, Point source, float degree) {
        source.x -= target.x;
        source.y -= target.y;
        double alpha = 0.0D;
        double beta = 0.0D;
        Point result = new Point();
        double dis = Math.sqrt((double)(source.x * source.x + source.y * source.y));
        if(source.x == 0 && source.y == 0) {
            return target;
        } else {
            if(source.x >= 0 && source.y >= 0) {
                alpha = Math.asin((double)source.y / dis);
            } else if(source.x < 0 && source.y >= 0) {
                alpha = Math.asin((double)Math.abs(source.x) / dis);
                ++alpha;
            } else if(source.x < 0 && source.y < 0) {
                alpha = Math.asin((double)Math.abs(source.y) / dis);
                alpha += 3.141592653589793D;
            } else if(source.x >= 0 && source.y < 0) {
                alpha = Math.asin((double)source.x / dis);
                alpha += 4.71238898038469D;
            }

            alpha = radianToDegree(alpha);
            beta = alpha + (double)degree;
            beta = degreeToRadian(beta);
            result.x = (int)Math.round(dis * Math.cos(beta));
            result.y = (int)Math.round(dis * Math.sin(beta));
            result.x += target.x;
            result.y += target.y;
            return result;
        }
    }

    public static double radianToDegree(double radian) {
        return radian * 180.0D / 3.141592653589793D;
    }

    public static double degreeToRadian(double degree) {
        return degree * 3.141592653589793D / 180.0D;
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.paint.setARGB(255, 255, 255, 255);
        this.paint.setStrokeWidth(2.0F);
        if(this.stickEditMode) {
            canvas.drawLine((float)this.np1.x, (float)this.np1.y, (float)this.np2.x, (float)this.np2.y, this.paint);
            canvas.drawLine((float)this.np2.x, (float)this.np2.y, (float)this.np3.x, (float)this.np3.y, this.paint);
            canvas.drawLine((float)this.np3.x, (float)this.np3.y, (float)this.np4.x, (float)this.np4.y, this.paint);
            canvas.drawLine((float)this.np4.x, (float)this.np4.y, (float)this.np1.x, (float)this.np1.y, this.paint);
            canvas.drawBitmap(this.delmB, (float)(this.iconP1.x - this.wW), (float)(this.iconP1.y - this.wH), this.paint);
            canvas.drawBitmap(this.ctrlmB, (float)(this.iconP2.x - this.wW), (float)(this.iconP2.y - this.wH), this.paint);
        }

        canvas.drawBitmap(this.mBitmap, this.matrix, this.paint);
        this.setViewWH(this.rotatedImageW, this.rotatedImageH, this.cpoint.x - this.rotatedImageW / 2, this.cpoint.y - this.rotatedImageH / 2);
    }

    public void drawRectR(int l, int t, int r, int b, float jd) {
        Point p1 = new Point(l, t);
        Point p2 = new Point(r, t);
        Point p3 = new Point(r, b);
        Point p4 = new Point(l, b);
        Point tp = new Point((l + r) / 2, (t + b) / 2);
        this.np1 = roationPoint(tp, p1, jd);
        this.np2 = roationPoint(tp, p2, jd);
        this.np3 = roationPoint(tp, p3, jd);
        this.np4 = roationPoint(tp, p4, jd);
        boolean w = false;
        boolean h = false;
        boolean maxn = false;
        boolean mixn = false;
        int maxn1 = this.np1.x;
        int mixn1 = this.np1.x;
        if(this.np2.x > maxn1) {
            maxn1 = this.np2.x;
        }

        if(this.np3.x > maxn1) {
            maxn1 = this.np3.x;
        }

        if(this.np4.x > maxn1) {
            maxn1 = this.np4.x;
        }

        if(this.np2.x < mixn1) {
            mixn1 = this.np2.x;
        }

        if(this.np3.x < mixn1) {
            mixn1 = this.np3.x;
        }

        if(this.np4.x < mixn1) {
            mixn1 = this.np4.x;
        }

        int w1 = maxn1 - mixn1;
        maxn1 = this.np1.y;
        mixn1 = this.np1.y;
        if(this.np2.y > maxn1) {
            maxn1 = this.np2.y;
        }

        if(this.np3.y > maxn1) {
            maxn1 = this.np3.y;
        }

        if(this.np4.y > maxn1) {
            maxn1 = this.np4.y;
        }

        if(this.np2.y < mixn1) {
            mixn1 = this.np2.y;
        }

        if(this.np3.y < mixn1) {
            mixn1 = this.np3.y;
        }

        if(this.np4.y < mixn1) {
            mixn1 = this.np4.y;
        }

        int h1 = maxn1 - mixn1;
        Point npc = this.intersects(this.np4, this.np2, this.np1, this.np3);
        this.dx = w1 / 2 - npc.x;
        this.dy = h1 / 2 - npc.y;
        this.np1.x = this.np1.x + this.dx + this.wW;
        this.np2.x = this.np2.x + this.dx + this.wW;
        this.np3.x = this.np3.x + this.dx + this.wW;
        this.np4.x = this.np4.x + this.dx + this.wW;
        this.np1.y = this.np1.y + this.dy + this.wH;
        this.np2.y = this.np2.y + this.dy + this.wH;
        this.np3.y = this.np3.y + this.dy + this.wH;
        this.np4.y = this.np4.y + this.dy + this.wH;
        this.rotatedImageW = w1;
        this.rotatedImageH = h1;
        this.iconP1 = this.np1;
        this.iconP2 = this.np3;
    }

    public Point intersects(Point sp3, Point sp4, Point sp1, Point sp2) {
        Point localPoint = new Point(0, 0);
        double num = (double)((sp4.y - sp3.y) * (sp3.x - sp1.x) - (sp4.x - sp3.x) * (sp3.y - sp1.y));
        double denom = (double)((sp4.y - sp3.y) * (sp2.x - sp1.x) - (sp4.x - sp3.x) * (sp2.y - sp1.y));
        localPoint.x = (int)((double)sp1.x + (double)(sp2.x - sp1.x) * num / denom);
        localPoint.y = (int)((double)sp1.y + (double)(sp2.y - sp1.y) * num / denom);
        return localPoint;
    }

    public int isactiondownicon(int x, int y) {
        int kk1 = (x - this.iconP1.x) * (x - this.iconP1.x) + (y - this.iconP1.y) * (y - this.iconP1.y);
        int kk2 = (x - this.iconP2.x) * (x - this.iconP2.x) + (y - this.iconP2.y) * (y - this.iconP2.y);
        System.out.println("kk1:" + kk1 + "  kk2:" + kk2 + "  x,y" + x + "|" + y);
        return kk1 < this.wW * this.wW?1:(kk2 < this.wW * this.wW?2:0);
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getAction() & 255) {
            case 0:
                this.pA.set(event.getX() + (float)this.viewL, event.getY() + (float)this.viewT);
                if(this.isactiondownicon((int)event.getX(), (int)event.getY()) == 2) {
                    this.mode = 4;
                } else if(this.isactiondownicon((int)event.getX(), (int)event.getY()) == 1) {
                    System.out.println("删除控件：" + event.getX() + "|" + event.getY());
                    this.stickerListener.onStickerModeChanged(this.sticknum, 1, this);
                } else {
                    this.mode = 1;
                    this.setStickEditMode(!this.stickEditMode);
                    this.invalidate();
                }
                break;
            case 1:
            case 5:
            case 6:
                this.mode = 0;
                break;
            case 2:
                if(this.mode == 4) {
                    float sf = 1.0F;
                    this.pB.set(event.getX() + (float)this.viewL, event.getY() + (float)this.viewT);
                    float realL = (float)Math.sqrt((double)((float)(this.mBitmap.getWidth() * this.mBitmap.getWidth() + this.mBitmap.getHeight() * this.mBitmap.getHeight()) / 4.0F));
                    float newL = (float)Math.sqrt((double)((this.pB.x - (float)this.cpoint.x) * (this.pB.x - (float)this.cpoint.x) + (this.pB.y - (float)this.cpoint.y) * (this.pB.y - (float)this.cpoint.y)));
                    sf = newL / realL;
                    double a = (double)this.spacing(this.pA.x, this.pA.y, (float)this.cpoint.x, (float)this.cpoint.y);
                    double b = (double)this.spacing(this.pB.x, this.pB.y, this.pA.x, this.pA.y);
                    double c = (double)this.spacing(this.pB.x, this.pB.y, (float)this.cpoint.x, (float)this.cpoint.y);
                    double cosB = (a * a + c * c - b * b) / (2.0D * a * c);
                    if(cosB > 1.0D) {
                        System.out.println(" sf:" + sf + " cosB:" + cosB);
                        cosB = 1.0D;
                    }

                    double angleB = Math.acos(cosB);
                    float newjd = (float)(angleB / 3.141592653589793D * 180.0D);
                    float p1x = this.pA.x - (float)this.cpoint.x;
                    float p2x = this.pB.x - (float)this.cpoint.x;
                    float p1y = this.pA.y - (float)this.cpoint.y;
                    float p2y = this.pB.y - (float)this.cpoint.y;
                    if(p1x == 0.0F) {
                        if(p2x > 0.0F && p1y >= 0.0F && p2y >= 0.0F) {
                            newjd = -newjd;
                        } else if(p2x < 0.0F && p1y < 0.0F && p2y < 0.0F) {
                            newjd = -newjd;
                        }
                    } else if(p2x == 0.0F) {
                        if(p1x < 0.0F && p1y >= 0.0F && p2y >= 0.0F) {
                            newjd = -newjd;
                        } else if(p1x > 0.0F && p1y < 0.0F && p2y < 0.0F) {
                            newjd = -newjd;
                        }
                    } else if(p1x != 0.0F && p2x != 0.0F && p1y / p1x < p2y / p2x) {
                        if(p1x < 0.0F && p2x > 0.0F && p1y >= 0.0F && p2y >= 0.0F) {
                            newjd = -newjd;
                        } else if(p2x < 0.0F && p1x > 0.0F && p1y < 0.0F && p2y < 0.0F) {
                            newjd = -newjd;
                        }
                    } else if((p2x >= 0.0F || p1x <= 0.0F || p1y < 0.0F || p2y < 0.0F) && (p2x <= 0.0F || p1x >= 0.0F || p1y >= 0.0F || p2y >= 0.0F)) {
                        newjd = -newjd;
                    }

                    this.pA.x = this.pB.x;
                    this.pA.y = this.pB.y;
                    if(sf == 0.0F) {
                        sf = 0.1F;
                    } else if(sf >= 3.0F) {
                        sf = 3.0F;
                    }

                    this.setImageBitmap(this.mBitmap, this.cpoint, this.jd + newjd, sf);
                }

                if(this.mode == 1) {
                    this.pB.set(event.getX() + (float)this.viewL, event.getY() + (float)this.viewT);
                    this.cpoint.x = (int)((float)this.cpoint.x + (this.pB.x - this.pA.x));
                    this.cpoint.y = (int)((float)this.cpoint.y + (this.pB.y - this.pA.y));
                    this.pA.x = this.pB.x;
                    this.pA.y = this.pB.y;
                    this.setCPoint(this.cpoint);
                }
            case 3:
            case 4:
        }

        return true;
    }

    private float spacing(float x1, float y1, float x2, float y2) {
        float x = x1 - x2;
        float y = y1 - y2;
        return (float) Math.sqrt(x * x + y * y);
    }

    public static int dip2px(Context context, float dpValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int)(dpValue * scale + 0.5F);
    }

    public void setOnStickerListener(HSuperImageView.OnStickerListener listener) {
        this.stickerListener = listener;
    }

    public boolean isStickEditMode() {
        return this.stickEditMode;
    }

    public void setStickEditMode(boolean stickEditMode) {
        this.stickEditMode = stickEditMode;
    }

    public boolean getStickEditMode() {
        return this.stickEditMode;
    }

    public interface OnStickerListener {
        void onStickerModeChanged(int var1, int var2, HSuperImageView var3);
    }
}
